﻿#define ONGUI_DEBUG

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

public class TcpClientModule : NetModuleBase
{

    /// <summary>
    /// 超时时间
    /// </summary>
    [SerializeField]
    private int timeOut = 3000;

    /// <summary>
    /// 是否处于连接状态
    /// </summary>
    [SerializeField]
    private bool isConnect = false;

#if ONGUI_DEBUG
    /// <summary>
    /// 是否处于Debug模式
    /// </summary>
    [SerializeField]
    protected bool isDebug = true;

#endif

    public long sendByteCount = 0;
    private TcpClientCore clientCore;
    private static TcpClientModule _instance;

    public static TcpClientModule Instance
    {
        get
        {
            if (_instance == null) throw new Exception("单例为空，禁止调用");
            return _instance;
        }
    }

    /// <summary>
    /// 初始化
    /// </summary>
    private void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        clientCore = new TcpClientCore();
        NetCore.InitNetCore(AddEvent);
    }

    // Use this for initialization
    void Start()
    {
       
    }
    protected override void Update()
    {
        base.Update();

#if ONGUI_DEBUG
        //byte[] buf = new byte[10240];
        //if (Input.GetKey(KeyCode.Space))
        //{
        //    byte[] lenBuf = BitConverter.GetBytes(buf.Length);
        //    SendMsgToQueue(lenBuf.Concat(buf).ToArray());
        //}
#endif
    }

#if ONGUI_DEBUG
    #region OnGUI 测试部分
    private string sendStr = "hello unity";
    [Space]
    [SerializeField]
    private int fontSize = 20;
    private bool isInitOnGUI = false;
    private void OnGUI()
    {

        if (!isDebug) return;
        //开始一个显示区域
        GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height));

        //开始最外层横向布局
        GUILayout.BeginHorizontal();
        //嵌套一个纵向布局
        GUILayout.BeginVertical();
        {
            //左上
        }
        //两个box之间上下对齐
        GUILayout.FlexibleSpace();
        {
            //左下
        }
        //结束嵌套的纵向局部
        GUILayout.EndVertical();

        //布局之间左右对齐
        GUILayout.FlexibleSpace();

        //嵌套一个纵向布局
        GUILayout.BeginVertical();

        {
            //右上
            TestGUI();
        }
        //两个box之间上下对齐
        GUILayout.FlexibleSpace();
        {
            //右下
        }
        //结束嵌套的纵向局部
        GUILayout.EndVertical();

        //结束最外层横向布局
        GUILayout.EndHorizontal();
        //结束显示区域
        GUILayout.EndArea();
    }
    private void TestGUI()
    {
        if (!isInitOnGUI)
        {
            isInitOnGUI = true;
            GUI.skin.button.fontSize = fontSize;
            GUI.skin.textArea.fontSize = fontSize;
            GUI.skin.textField.fontSize = fontSize;
            GUI.skin.label.fontSize = fontSize;
            GUI.skin.toggle.fontSize = fontSize;
        }

        if (!isConnect)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Label("IP:");
            ip = GUILayout.TextField(ip, 20);
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("Port:");
            port = GUILayout.TextField(port, 5);
            GUILayout.EndHorizontal();
            isPacketDecode = GUILayout.Toggle(isPacketDecode, "添加长度发送");
            if (GUILayout.Button("连接服务器"))
            {
                Connect();
            }
        }
        else
        {
            sendStr = GUILayout.TextArea(sendStr);
            GUILayout.Label("SendBytes:" + sendByteCount);
            if (isPacketDecode)
            {
                //携带数据长度
                if (GUILayout.Button("发送数据"))
                {
                    SendMsgToQueue(Encoding.UTF8.GetBytes(sendStr));
                }
            }
            else
            {
                if (GUILayout.Button("发送数据"))
                {
                    SendMsgToQueue(Encoding.UTF8.GetBytes(sendStr));
                }
            }
            if (GUILayout.Button("断开连接"))
            {
                Disconnect();
            }
        }
    }
    #endregion
#endif
    /// </summary>
    /// 连接服务器
    /// </summary>
    public void Connect()
    {
        clientCore.Connect(ip, port, timeOut, isPacketDecode);
    }
    /// <summary>
    /// 断开连接
    /// </summary>
    public void Disconnect()
    {
        clientCore.Disconnect();
    }

    private void OnDestroy()
    {
        Disconnect();
        NetCore.ResetNetCore(AddEvent);
    }

    /// <summary>
    /// 发送消息到队列 外部发送消息统一调用接口
    /// </summary>
    /// <param name="msg"></param>
    public void SendMsgToQueue(byte[] msg)
    {
        if(isPacketDecode)
        {
            if (msg.Length <= 4 && !isConnect) return;
            byte[] buff = BitConverter.GetBytes(msg.Length);
            buff = buff.Concat(msg).ToArray();
            lock (sendList)
                sendList.Add(buff);
        }
        else
        {
            if (msg.Length <= 0 && !isConnect) return;
            lock (sendList)
                sendList.Add(msg);
        }
        
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    protected override void SendAllMsg()
    {
        if (sendList.Count <= 0) return;

        byte[][] msgs = null;
        lock (sendList)
        {
            msgs = sendList.ToArray();
            sendList.Clear();
        }
        for (int i = 0; i < msgs.Length; i++)
        {
            sendByteCount += clientCore.Send(msgs[i]);
        }
    }

    /// <summary>
    /// 收到消息
    /// </summary>
    /// <param name="msg">msg</param>
    protected override void SC_ReceiveMessage(byte[] msg)
    {
        NetCore.Log(Encoding.UTF8.GetString(msg));
        this.transform.Rotate(Vector3.forward * 10);
    }

    /// <summary>
    /// 断开时调用
    /// </summary>
    /// <param name="msg">断开详情</param>
    /// <param name="cp">当为客户端模式时忽略该参数(忽略该参数)</param>
    protected override void SC_Disconnect(string msg)
    {
        NetCore.Log(msg);
        isConnect = false;
        sendByteCount = 0;
    }

    protected override void Comm_IPEndPointError(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void Comm_SARThreadFailed(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void SC_BeginConnect()
    {
        NetCore.Log("开始连接服务器");
    }
    protected override void SC_ConnectFailed(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void SC_ConnectSuccess()
    {
        isConnect = true;
        NetCore.Log("连接成功");
    }
}
